﻿using Blog.Core.Common.Helper;
using Blog.Core.IServices;
using Blog.Core.Model;
using Quartz;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using Blog.Core.Model.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Logging;

/// <summary>
/// 这里要注意下，命名空间和程序集是一样的，不然反射不到
/// </summary>
namespace Blog.Core.Tasks
{
    public class Job_Blogs_Quartz : JobBase, IJob
    {
        public IbookServices _bookServices { get; set; }
        public IchapterServices _chapterServices { get; set; }
        string baseUrl = "https://www.xbiquge.la";
        private readonly ILogger<Job_Blogs_Quartz> _loggerHelper;
        public Job_Blogs_Quartz(IbookServices bookServices, ILogger<Job_Blogs_Quartz> loggerHelper, ITasksQzServices tasksQzServices, IchapterServices chapterServices)
        {
            _bookServices = bookServices;
            _chapterServices = chapterServices;
            _tasksQzServices = tasksQzServices;
            _loggerHelper = loggerHelper;
        }
        public async Task Execute(IJobExecutionContext context)
        {
            var executeLog = await ExecuteJob(context, async () => await Run(context));
        }
        public async Task Run(IJobExecutionContext context)
        {
            List<book> books = await _bookServices.Query(b => b.bState == 1);
            foreach (book book in books)
            {
                MessageModel<string> data = await GetCatalogue(book);
                if (data.success)
                {
                    _loggerHelper.LogInformation("【" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "】 " + book.bName + "：更新" + data.msg + "条");
                }
                else
                {
                    _loggerHelper.LogError("【" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "】 " + book.bName + "更新失败，原因：" + data.msg);
                }
            }
        }
        /// <summary>
        /// 获取小说章节目录
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public async Task<MessageModel<string>> GetCatalogue(book book)
        {
            var data = new MessageModel<string>();
            try
            {
                string response = await HttpHelper.GetAsync(book.url);
                // 匹配所有a标签目录 <dd><a[^>]*href=([""'])?(?<href>[^'""]+)\1[^>]*>*.*</a></dd>
                // 匹配封面图片      <div.*?id=\"fmimg\">(?<html>[\s\S]*?)</div>
                // 匹配书名称        <meta property="og:novel:book_name"(.*?)>
                // 匹配作者          <meta property="og:novel:author"(.*?)>
                // 匹配类型          <meta property="og:novel:category"(.*?)>
                // 匹配封面图片      <meta property="og:image"(.*?)>
                
                Regex rx = new Regex(@"<dd><a[^>]*href=([""'])?(?<href>[^'""]+)\1[^>]*>*.*</a></dd>");
                MatchCollection matches = rx.Matches(response);
                rx = new Regex("<a .*?href=['\"](.*?)['\"].*?>(.*?)</a>");
                List<chapter> chapters = await _chapterServices.Query(c => c.bId == book.bId);
                foreach (var item in matches)
                {
                    string href = rx.Match(item.ToString()).Groups[1].Value;
                    string text = rx.Match(item.ToString()).Groups[2].Value;
                    List<chapter> cs = chapters.Where(c => c.cName == text || c.url == href).ToList();
                    if (cs.Count == 0)
                    {
                        chapter chapter = new chapter();
                        chapter.bId = book.bId;
                        chapter.cName = text;
                        chapter.url = href;
                        chapter.updateTime = DateTime.Now;
                        chapter.cId = await _chapterServices.Add(chapter);
                    }
                }
                chapters = await _chapterServices.Query(c => c.bId == book.bId, " cId asc ");
                chapters = chapters.Where(c => c.cContent == null).ToList();
                int index = 0;
                for (int i = 0; i < chapters.Count; i++)
                {
                    string content = await HttpHelper.GetAsync(baseUrl + chapters[i].url);
                    Regex rx_content = new Regex("<div.*?id=\"content\">(?<html>[\\s\\S]*?)</div>");
                    Match match = rx_content.Match(content);
                    chapters[i].cContent = match.Value;
                    await _chapterServices.Update(chapters[i]);
                    if (i == chapters.Count - 1)
                    {
                        book.newChapter = chapters[i].cName;
                        book.updateTime = DateTime.Now;
                        await _bookServices.Update(book);
                    }
                    index++;
                }
                data.success = true;
                data.msg = index.ToString();
            }
            catch (Exception ex)
            {
                data.success = false;
                data.msg = "失败！原因：" + ex.Message;
            }
            return data;
        }
    }
}
